home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / VGX / shadows / bintoglo.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  8KB  |  280 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.     bintoglob.c - Spin 3D object file format to glo_object file format
  19.     converter.
  20.  
  21.     Tim Heidmann, Silicon Graphics
  22.     June 26, 1991
  23. */
  24. #include <stdio.h>
  25. #include "fastobj.h"
  26. #include "glo_obj.h"
  27. #include "vect.h"
  28. #define TRUE 1
  29. #define FALSE 0
  30.  
  31. void
  32. NoDups(glo_ObjPtr theObj, int nList, int nTriplets);
  33. int
  34. NoDegen(glo_ObjPtr theObj, int nList, int nTriplets);
  35.  
  36. main(int argc, char *argv[]) {
  37.     fastobj *myFObj;
  38.     glo_ObjPtr myGLObj;
  39.     int nTriplets, nQuads, nList, i, j, k, iTriplet;
  40.     int *pList;
  41.     float *pData;
  42.     char *inFile, *outFile;
  43.     int flipOrder;
  44.  
  45.     if (argc == 3) {
  46.     flipOrder = FALSE;
  47.     inFile = argv[1]; outFile = argv[2];
  48.     } else if (argc == 4 && argv[1][0] == '-' && argv[1][1] == 'f') {
  49.     flipOrder = TRUE;
  50.     inFile = argv[2]; outFile = argv[3];
  51.     } else {
  52.     fprintf(stderr, "usage: %s [-f] <infile.bin> <outfile.glo>\n", argv[0]);
  53.     exit(1);
  54.     }
  55.  
  56.     /* Read a .bin file */
  57.     myFObj = readfastobj(inFile);
  58.     printf("%s: %d points (%d polygons)\n", inFile,
  59.     myFObj->npoints, myFObj->npoints/4);
  60.  
  61.     /* Convert fastobj structure to glo_object */
  62.     nTriplets = myFObj->npoints*2;
  63.     nQuads = myFObj->npoints/4;
  64.     if (myFObj->colors)
  65.     /* Color per vertex.  Ignore colors. */
  66.     nList = 1 + (2 + 4) * nQuads + 1;
  67.     else
  68.     /* Normal per vertex. Use them. */
  69.     nList = 1 + (2 + 4 + 4) * nQuads + 1;
  70.  
  71.     myGLObj = (glo_ObjPtr) malloc(sizeof(glo_ObjTyp));
  72.     myGLObj->list = (int *) malloc(sizeof(int)*nList);
  73.     myGLObj->t = (float (*)[3]) malloc(sizeof(float) * 3 * nTriplets);
  74.  
  75.     /* March through fastobj data, copying to vertex and command list */
  76.     pList = myGLObj->list;
  77.     pData = (float *) myFObj->data;
  78.     iTriplet = 0;
  79.     if (!myFObj->colors) {
  80.     /* Normal per vertex, keep it all */
  81.     printf("Normal per vertex\n");
  82.     *pList++ = NPERV;
  83.     for (i=0; i<nQuads; i++) {
  84.         *pList++ = BGNPOLY;
  85.         for (j=0; j<4; j++) {
  86.         /* Normal */
  87.         for (k=0; k<3; k++)
  88.             myGLObj->t[iTriplet][k] = *pData++;
  89.         pData++; /* fastobj keeps points as float[4]'s */
  90.         pList[2 * (flipOrder ? 3-j : j)] = iTriplet++;
  91.  
  92.         /* Vertex */
  93.         for (k=0; k<3; k++)
  94.             myGLObj->t[iTriplet][k] = *pData++;
  95.         pData++; /* fastobj keeps points as float[4]'s */
  96.         pList[2 * (flipOrder ? 3-j : j) + 1] = iTriplet++;
  97.         }
  98.         pList += 8;
  99.         *pList++ = ENDPOLY;
  100.     }
  101.     *pList++ = ENDLIST;
  102.     } else {
  103.     /* Ignore color per vertex info */
  104.     printf("Color per vertex\n");
  105.     *pList++ = NONORM;
  106.     for (i=0; i<nQuads; i++) {
  107.         *pList++ = BGNPOLY;
  108.         for (j=0; j<4; j++) {
  109.         pData += 4;    /* Skip over color info */
  110.  
  111.         for (k=0; k<3; k++)
  112.             myGLObj->t[iTriplet][k] = *pData++;
  113.         pData++;
  114.         pList[flipOrder ? 3-j : j] = iTriplet++;
  115.         }
  116.         pList += 4;
  117.         *pList++ = ENDPOLY;
  118.     }
  119.     *pList++ = ENDLIST;
  120.     }
  121.  
  122.     /* Remove duplicate triplets, and degenerate points and polys */
  123.     nTriplets = NoDupTrips(myGLObj, nList, nTriplets);
  124.     nList = NoDegen(myGLObj, nList, nTriplets);
  125.  
  126.     /* Write the .glo file */
  127.     glo_WriteObj(myGLObj, outFile);
  128. }
  129.  
  130. #define MARGIN 0.0005
  131.  
  132. int
  133. NoDupTrips(glo_ObjPtr theObj, int nList, int nTriplets) {
  134.     /* Step through triplet list, eliminating duplicates. */
  135.     int i, iTrip, iList, iCheck, nDuplicates;
  136.     int *pList;
  137.     short *tripletMap, *uniqueFlag;
  138.     float (*pTrip)[3], (*pCheck)[3], (*pNew)[3], (*newT)[3];
  139.  
  140.     /* Keep a map of old triplet indices to indices into the list
  141.        with the duplicate values removed.
  142.        Also keep a flag for each triplet for if it's unique and gets kept. */
  143.     tripletMap = (short *) malloc(sizeof(short) * nTriplets);
  144.     uniqueFlag = (short *) malloc(sizeof(short) * nTriplets);
  145.  
  146.     /* Check for duplicate triplets. Remember a mapping for each one */
  147.     nDuplicates = 0;
  148.     for (iTrip=0, pTrip=theObj->t; iTrip<nTriplets; iTrip++, pTrip++) {
  149.     tripletMap[iTrip] = iTrip - nDuplicates;
  150.     uniqueFlag[iTrip] = TRUE;
  151.     for (iCheck=0, pCheck=theObj->t; iCheck<iTrip; iCheck++, pCheck++)
  152.         if (fabs((*pTrip)[0] - (*pCheck)[0]) < MARGIN &&
  153.             fabs((*pTrip)[1] - (*pCheck)[1]) < MARGIN &&
  154.             fabs((*pTrip)[2] - (*pCheck)[2]) < MARGIN) {
  155.             tripletMap[iTrip] = tripletMap[iCheck];
  156.             uniqueFlag[iTrip] = FALSE;
  157.             nDuplicates++;
  158.             break;
  159.         }
  160.     }
  161.  
  162.     /* Condense the triplet list, keeping only unique values. */
  163.     for (iTrip=0; iTrip<nTriplets && uniqueFlag[iTrip]; iTrip++) ;
  164.     for (pNew = pTrip = theObj->t+iTrip; iTrip<nTriplets; iTrip++, pTrip++)
  165.     if (uniqueFlag[iTrip]) {
  166.         for (i=0; i<3; i++)
  167.         (*pNew)[i] = (*pTrip)[i];
  168.         pNew++;
  169.     }
  170.  
  171.     /* Now reset indices in the list to point at the unique triplet */
  172.     for (iList=0, pList=theObj->list; iList<nList; iList++, pList++)
  173.     if (*pList >= 0) *pList = tripletMap[*pList];
  174.  
  175.     /* Finally, free working memory and return. */
  176.     free(tripletMap);
  177.     free(uniqueFlag);
  178.     printf("%d duplicate triplets (out of %d)\n", nDuplicates, nTriplets);
  179.     return nTriplets - nDuplicates;
  180. }
  181.  
  182. int
  183. NoDegen(glo_ObjPtr theObj, int nList, int nTriplets) {
  184.     /* Find and eliminate degenerate polygons and polygon edges */
  185.     int nVertices, nDest, nThisDegenV, nDegenV, nDegenP;
  186.     int done, leadingNormal, pervNormal;
  187.     int firstVertex, firstNormal, lastVertex, lastNormal, thisVertex;
  188.     int *pStart, *pDest, *pList;
  189.  
  190.     nDegenV = 0;
  191.     nDegenP = 0;
  192.     nDest = 0;
  193.     for (done = FALSE, pDest = pList = theObj->list;; ) {
  194.  
  195.     /* Find the next element, copying commands, following mode changes */
  196.     for (;*pList < 0; *pDest++ = *pList++) {
  197.         nDest++;
  198.         switch (*pList) {
  199.         case  NONORM: leadingNormal = FALSE; pervNormal = FALSE; break;
  200.         case   NPERV: leadingNormal = FALSE; pervNormal = TRUE ; break;
  201.         case   NPERP: leadingNormal = TRUE ; pervNormal = FALSE; break;
  202.         case ENDLIST: done = TRUE; break;
  203.         default: ;
  204.         }
  205.     }
  206.     if (done) break;
  207.  
  208.     /* Remember start in case we need to undo this poly */
  209.     pStart = pDest;
  210.  
  211.     /* Look at the first vertex */
  212.     if (leadingNormal) *pDest++ = *pList++;
  213.     if (pervNormal) firstNormal = lastNormal = *pList++;
  214.     firstVertex = lastVertex = *pList++;
  215.  
  216.     /* Add each successive vertex, checking against the previous one */
  217.     nVertices = 0;
  218.     nThisDegenV = 0;
  219.     while (*pList >= 0) {
  220.         /* More vertices to check */
  221.         if (pervNormal) {
  222.         if (pList[1] != lastVertex) {
  223.             *pDest++ = lastNormal;
  224.             *pDest++ = lastVertex;
  225.             lastNormal = *pList++;
  226.             lastVertex = *pList++;
  227.             nVertices++;
  228.         }
  229.         else {
  230.             pList += 2;
  231.             nThisDegenV++;
  232.         }
  233.         } else  {
  234.         if (pList[0] != lastVertex) {
  235.             *pDest++ = lastVertex;
  236.             lastVertex = *pList++;
  237.             nVertices++;
  238.         }
  239.         else {
  240.             pList++;
  241.             nThisDegenV++;
  242.         }
  243.         }
  244.     }
  245.  
  246.     /* That was the last vertex.  Check against first before adding. */
  247.     if (pervNormal) {
  248.         if (lastVertex != firstVertex) {
  249.         *pDest++ = lastNormal;
  250.         *pDest++ = lastVertex;
  251.         nVertices++;
  252.         }
  253.         else nThisDegenV++;
  254.     } else {
  255.         if (lastVertex != firstVertex) {
  256.         *pDest++ = lastVertex;
  257.         nVertices++;
  258.         }
  259.         else nThisDegenV++;
  260.     }
  261.  
  262.     /* Check for and delete degenerate polygons */
  263.     if (nVertices<3) {
  264.         pDest = pStart - 1;  /* Go back to before the BGN... */
  265.         nDest--;
  266.         pList++;             /* And swallow the following END... */
  267.         nDegenP++;
  268.     }
  269.     else {
  270.         /* Good polygon, add to the tally */
  271.         nDest += leadingNormal?1:0 + pervNormal?2*nVertices:nVertices;
  272.         nDegenV += nThisDegenV;
  273.     }
  274.     }
  275.  
  276.     printf("%d degenerate vertices, %d degenerate polygons removed.\n",
  277.     nDegenV, nDegenP);
  278.     return nDest;
  279. }
  280.